home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Rice_CMS / gopher24 / gopsrv.$exec < prev    next >
Encoding:
Text File  |  1993-01-25  |  28.1 KB  |  356 lines

  1. /*                                                                      00010000
  2.  *        Name: GOPSRV EXEC                                             00020000
  3.  *              A CMS-based Gopher Server                               00030000
  4.  *              Based on the original, GOPHERD EXEC, from 2.3.          00040000
  5.  *      Author: Rick Troth, Rice University, Information Systems        00050000
  6.  *        Date: 1992-Apr-21, Aug-07, Oct-14, Dec-11, 1993-Jan-15        00060000
  7.  */                                                                     00070000
  8.                                                                         00080000
  9. /*                                                                      00090000
  10.  *      Copyright 1993 Richard M. Troth.   This software was developed  00100000
  11.  *      with resources provided by Rice University and is intended      00110000
  12.  *      to serve Rice's user community.   Rice has benefitted greatly   00120000
  13.  *      from the free distribution of software,  therefore distribution 00130000
  14.  *      of unmodified copies of this material is not restricted.        00140000
  15.  *      You may change your own copy as needed.   Neither Rice          00150000
  16.  *      University nor any of its employees or students shall be held   00160000
  17.  *      liable for damages resulting from the use of this software.     00170000
  18.  */                                                                     00180000
  19.                                                                         00190000
  20. /*                                                                      00200000
  21.  *       Calls:                                                         00210000
  22.  *              GOPSRVLS REXX     -- to read files and menus            00220000
  23.  *              GOPSRVRP REXX     -- to resolve gopher paths            00230000
  24.  *              GOPSRVMB REXX     -- to build menus for the client      00240000
  25.  *                                                                      00250000
  26.  *        Note: this program does *not* use RXSOCKET's translation      00260000
  27.  *              option.   Translation between ASCII and EBCDIC          00270000
  28.  *              is determined by the type of file requested.            00280000
  29.  */                                                                     00290000
  30.                                                                         00300000
  31. progid = "CMS Gopher 2.4.0 server"                                      00310000
  32. gopher = "Gopher"                                                       00320000
  33. timeout = 5                                                             00330000
  34.                                                                         00340000
  35. Parse Source . . . . . arg0 .                                           00350000
  36. argo = arg0 || ':'                                                      00360000
  37. Parse Upper Arg root port . '(' . ')' .                                 00370000
  38.                                                                         00380000
  39. Address "COMMAND"                                                       00390000
  40.                                                                         00400000
  41. 'SET LANGUAGE (ADD GOP USER'                                            00410000
  42.                                                                         00420000
  43. host = "localhost"      /*  this will be reset to the actual name of  * 00430000
  44.                          *  this host after RXSOCKET is initialized.  */00440000
  45.                                                                         00450000
  46.     stdin  = 0                                                          00460000
  47.     stdout = 1                                                          00470000
  48.     stderr = 2                                                          00480000
  49.                                                                         00490000
  50. Say argo progid "starting"                                              00500000
  51.                                                                         00510000
  52. logpipe = "CONSOLE"                                                     00520000
  53. _root = Userid()                                                        00530000
  54. _port = 70                                                              00540000
  55. 'PIPE < GOPHERD CONFIG * | STEM CONFIG.'                                00550000
  56. If rc = 0 Then                                                          00560000
  57. Do i = 1 to config.0                                                    00570000
  58.     If Left(config.i,1) = '*' Then Iterate                              00580000
  59.     If Left(config.i,1) = '#' Then Iterate                              00590000
  60.     If Index(config.i,'=') = 0 Then Iterate                             00600000
  61.     Parse Var config.i var '=' val                                      00610000
  62.     Upper var                                                           00620000
  63.     Select  /*  var  */                                                 00630000
  64.         When  Abbrev("LOGPIPE",var,3)   Then  logpipe = val             00640000
  65.         When  Abbrev("ROOT",var,4)      Then  _root = val               00650000
  66.         When  Abbrev("PORT",var,4)      Then  _port = val               00660000
  67.         Otherwise 'XMITMSG 2 VAR (ERRMSG'                               00670000
  68.         End  /*  Select  var  */                                        00680000
  69.     End  /*  Do  For  */                                                00690000
  70.                                                                         00700000
  71. If root = "" Then root = _root                                          00710000
  72. If port = "" Then port = _port                                          00720000
  73.                                                                         00730000
  74. If ^Datatype(port,'N') Then Do                                          00740000
  75.     /*  "Gopher TCP/IP service port must be numeric."  */               00750000
  76.     'XMITMSG 126 (APPLID GOP CALLER SRV ERRMSG'                         00760000
  77.     Exit 24                                                             00770000
  78.     End  /*  If  ..  Do  */                                             00780000
  79.                                                                         00790000
  80. /*                                                                      00800000
  81.  *   Initialize RXSOCKET                                                00810000
  82.  */                                                                     00820000
  83. maxdesc = Socket('Initialize', gopher)                                  00830000
  84. If maxdesc = "-1" Then Do                                               00840000
  85.     Say argo tcperror()                                                 00850000
  86.     Exit -1                                                             00860000
  87.     End  /*  If  ..  Do  */                                             00870000
  88. Say argo "RXSOCKET Initialized for" maxdesc "descriptors"               00880000
  89.                                                                         00890000
  90.                                                                         00900000
  91. /*                                                                      00910000
  92.  *   Request the name of this host                                      00920000
  93.  */                                                                     00930000
  94. rc = Socket('GetHostName', 'HOST')                                      00940000
  95. If rc = "-1" Then Do                                                    00950000
  96.     Say argo tcperror()                                                 00960000
  97.     Exit -1                                                             00970000
  98.     End  /*  If  ..  Do  */                                             00980000
  99. Say argo "LocalHost =" host                                             00990000
  100.                                                                         01000000
  101.                                                                         01010000
  102. /*                                                                      01020000
  103.  *   Request a new socket descriptor (TCP protocol)                     01030000
  104.  */                                                                     01040000
  105. socket = Socket('Socket', 'AF_INET', 'Sock_Stream')                     01050000
  106. If socket = "-1" Then Do                                                01060000
  107.     Say argo tcperror()                                                 01070000
  108.     Exit -1                                                             01080000
  109.     End  /*  If  ..  Do  */                                             01090000
  110. Say argo "Primary socket =" socket                                      01100000
  111.                                                                         01110000
  112.                                                                         01120000
  113. /*                                                                      01130000
  114.  *   Set this socket to non-blocking mode                               01140000
  115.  */                                                                     01150000
  116. rc = Socket('Ioctl', socket, 'FIONBIO', 1)                              01160000
  117. If rc = "-1" Then                                                       01170000
  118.     Say argo tcperror()                                                 01180000
  119.                                                                         01190000
  120.                                                                         01200000
  121. /*                                                                      01210000
  122.  *                                                                      01220000
  123.  */                                                                     01230000
  124. name = AF_INET || Htons(port)                                           01240000
  125.                                                                         01250000
  126. rc = Socket('Bind', socket, name)                                       01260000
  127. If rc = "-1" Then Do                                                    01270000
  128.     Say argo tcperror()                                                 01280000
  129.     Exit -1                                                             01290000
  130.     End  /*  If  ..  Do  */                                             01300000
  131. Say argo "Bound to port" port                                           01310000
  132.                                                                         01320000
  133.                                                                         01330000
  134. /*                                                                      01340000
  135.  *                                                                      01350000
  136.  */                                                                     01360000
  137. rc = Socket('Listen', socket, maxdesc)                                  01370000
  138. If rc = "-1" Then Do                                                    01380000
  139.     Say argo tcperror()                                                 01390000
  140.     Exit -1                                                             01400000
  141.     End  /*  If  ..  Do  */                                             01410000
  142. /*  Say argo "Listening ..."  */                                        01420000
  143.                                                                         01430000
  144. /*  UNIX and VMS style logging:  */                                     01440000
  145. Parse Value Date('S') With 1 yy 5 mm 7 dd 9 .                           01450000
  146. day = Left(Date('W'),3)                                                 01460000
  147. mon = Left(Date('M'),3)                                                 01470000
  148. time = Time()                                                           01480000
  149. userid = Userid()                                                       01490000
  150. /*  "Starting gopher daemon" Userid()  */                               01500000
  151. 'PIPE COMMAND XMITMSG 120 DAY MON DD TIME YY HOST USERID' ,             01510000
  152.         '(APPLID GOP CALLER SRV ERRMSG |' logpipe                       01520000
  153.                                                                         01530000
  154. Say argo progid "waiting for a connection"                              01540000
  155.                                                                         01550000
  156. 'GLOBALV SELECT GOPHERD PUT HOST PORT ROOT'                             01560000
  157.                                                                         01570000
  158. Do Forever                                                              01580000
  159.                                                                         01590000
  160.     rc = FD_ZERO('readmask')            /* must be reset each time */   01600000
  161.     rc = FD_SET(socket, 'readmask')                                     01610000
  162.     rc = FD_SET(stdin, 'readmask')                                      01620000
  163.                                                                         01630000
  164.     Say "*"     /* waiting */                                           01640000
  165.     rc = Socket('Select', socket + 1, 'readmask', 0, 0, 0)              01650000
  166.     If rc = "-1" Then Do                                                01660000
  167.         Say argo tcperror()                                             01670000
  168.         Leave                                                           01680000
  169.         End  /*  If  ..  Do  */                                         01690000
  170.                                                                         01700000
  171.     If FD_ISSET(stdin, 'readmask') = 1 Then Leave                       01710000
  172.     If FD_ISSET(socket, 'readmask') ^= 1 Then Iterate                   01720000
  173.                                                                         01730000
  174.     /*                                                                  01740000
  175.      *                                                                  01750000
  176.      */                                                                 01760000
  177.     ns = Socket('Accept', socket, 'CLIENT')                             01770000
  178.     If ns = "-1" Then Do                                                01780000
  179.         Say argo tcperror()                                             01790000
  180.         Leave                                                           01800000
  181.         End  /*  If  ..  Do  */                                         01810000
  182.                                                                         01820000
  183.     Say argo "Accepted" ns "at" Time() "client" c2x(client)             01830000
  184.     Parse Var client . 5 r1 +1 r2 +1 r3 +1 r4 +1 .                      01840000
  185.     cipa = c2d(r1) || "." || c2d(r2) || "." || ,                        01850000
  186.            c2d(r3) || "." || c2d(r4)                                    01860000
  187.     /*  Say argo "Client's IP address is" cipa  */                      01870000
  188.                                                                         01880000
  189.     /*  UNIX and VMS style logging:  */                                 01890000
  190.     Parse Value Date('S') With 1 yyyy 5 mm 7 dd 9 .                     01900000
  191.     day = Left(Date('W'),3)                                             01910000
  192.     mon = Left(Date('M'),3)                                             01920000
  193.     time = Time()                                                       01930000
  194.                                                                         01940000
  195.     /*                                                                  01950000
  196.      *   Loop, reading the query line from the client.                  01960000
  197.      */                                                                 01970000
  198.     path = ""                                                           01980000
  199.     Do Forever                                                          01990000
  200.                                                                         02000000
  201.         rc = FD_ZERO('readmask')        /* must be reset each time */   02010000
  202.         rc = FD_SET(ns, 'readmask')                                     02020000
  203.                                                                         02030000
  204.         rc = Socket('Select', ns + 1, 'readmask', 0, 0, timeout)        02040000
  205.         If rc = "-1" Then Do                                            02050000
  206.             Say argo tcperror()                                         02060000
  207.             Exit -1                                                     02070000
  208.             End  /*  If  ..  Do  */                                     02080000
  209.                                                                         02090000
  210.         If FD_ISSET(ns, 'readmask') ^= 1 Then Leave                     02100000
  211.                                                                         02110000
  212.         pack = ""                                                       02120000
  213.         bytes_in = Socket('Read', ns, 'PACK')                           02130000
  214.         If bytes_in = "-1" Then                                         02140000
  215.             Say argo tcperror()                                         02150000
  216.         If bytes_in < 1 Then Leave                                      02160000
  217.         If Index(pack,'0A'x) > 0 Then Leave /* ASCII LF */              02170000
  218.         If Index(pack,'0D'x) > 0 Then Leave /* ASCII CR */              02180000
  219.         path = path || pack                                             02190000
  220.     End                                                                 02200000
  221.     path = path || pack                                                 02210000
  222.                                                                         02220000
  223.     Parse Var path path '0A'x .     /* ASCII LF */                      02230000
  224.     Parse Var path path '0D'x .     /* ASCII CR */                      02240000
  225.     'PIPE VAR PATH | A2E | VAR PATH'                                    02250000
  226.                                                                         02260000
  227.     /*  refresh disk access  (same procedure as used by GONE EXEC)  */  02270000
  228.     'PIPE CMS QUERY DISK | DROP | STEM STEM.'                           02280000
  229.     Do i = 1 to stem.0                                                  02290000
  230.         Parse Var stem.i . 8 va 12 fm .                                 02300000
  231.         If Left(va,3) = "DIR" Then Iterate                              02310000
  232.         'DISKWRIT' Left(fm,1)                                           02320000
  233.         If rc = 1 Then 'ACCESS' va fm                                   02330000
  234.         End  /*  Do  For  */                                            02340000
  235.                                                                         02350000
  236.     client = cipa                                                       02360000
  237.     'GLOBALV SELECT GOPHERD PUT CLIENT'                                 02370000
  238.                                                                         02380000
  239.                                                                         02390000
  240. Parse Var path path '05'x parm                                          02400000
  241. Say argo "Requesting:" path                                             02410000
  242. If parm ^= "" Then Say argo "+ Parms:" parm                             02420000
  243.                                                                         02430000
  244. Select  /*  type  */                                                    02440000
  245.                                                                         02450000
  246.     When path = "" Then Do                                              02460000
  247.         type = '1'                                                      02470000
  248.         logmsg = 121    /*  "Root Connection"  */                       02480000
  249.         End  /*  When  ..  Do  */                                       02490000
  250.                                                                         02500000
  251.     When Left(path,1) = '1' Then Do                                     02510000
  252.         Parse Var path 1 type 2 path                                    02520000
  253.         logmsg = 122    /*  "retrieved directory" path  */              02530000
  254.         End  /*  When  ..  Do  */                                       02540000
  255.                                                                         02550000
  256.     When Left(path,1) = '7' Then Do                                     02560000
  257.         Parse Var path 1 type 2 path                                    02570000
  258.         logmsg = 125    /*  "searched directory" path  */               02580000
  259.         End  /*  When  ..  Do  */                                       02590000
  260.                                                                         02600000
  261.     When Left(path,1) = '/' Then Do                                     02610000
  262.         type = '0'                                                      02620000
  263.         logmsg = 123    /*  "retrieved file" path  */                   02630000
  264.         End  /*  When  ..  Do  */                                       02640000
  265.                                                                         02650000
  266.     Otherwise Do                                                        02660000
  267.         Parse Var path 1 type 2 path                                    02670000
  268.         logmsg = 123    /*  "retrieved file" path  */                   02680000
  269.         End  /*  Otherwise  Do  */                                      02690000
  270.                                                                         02700000
  271.     End  /*  Select  type  */                                           02710000
  272.                                                                         02720000
  273. 'GLOBALV SELECT GOPHERD PUT PATH PARM'                                  02730000
  274. 'GLOBALV SELECT GOPHERD SET MENU'                                       02740000
  275.                                                                         02750000
  276. Select  /*  type  */                                                    02760000
  277.                                                                         02770000
  278.     When type = "0" Then        /* plain text file */                   02780000
  279.         pipe = 'APPEND LITERAL .' || ,                                  02790000
  280.             '| E2A | SPEC 1-* 1 x0D0A NEXT'                             02800000
  281.                                                                         02810000
  282.     When type = "1" Then        /* menu */                              02820000
  283.         pipe = 'GOPSRVMB | APPEND LITERAL .' || ,                       02830000
  284.             '| E2A | SPEC 1-* 1 x0D0A NEXT'                             02840000
  285.                                                                         02850000
  286.     When type = "7" Then        /* menu with search */                  02860000
  287.         pipe = 'GOPSRVYS' parm '| GOPSRVMB | APPEND LITERAL .' || ,     02870000
  288.             '| E2A | SPEC 1-* 1 x0D0A NEXT'                             02880000
  289.                                                                         02890000
  290.     When type = "9" | ,         /* binary */                            02900000
  291.          type = "4" | ,         /* Mac file, send as binary */          02910000
  292.          type = "5" | ,         /* PC file, send as binary */           02920000
  293.          type = "I" | ,         /* send pictures as binary */           02930000
  294.          type = "s" Then        /* sound, send as binary */             02940000
  295. pipe = 'FBLOCK 8192'    /*  default processing  */                      02950000
  296.                                                                         02960000
  297.     When type = "p" Then        /* PostScript */                        02970000
  298.         pipe = 'E2A | SPEC 1-* 1 x0D0A NEXT'                            02980000
  299.                                                                         02990000
  300.     When type = "r" | ,         /* record oriented file */              03000000
  301.          type = "v" Then        /* var-length records */                03010000
  302.         pipe = 'BLOCK 65531 CMS |' pipe                                 03020000
  303.                                                                         03030000
  304.     Otherwise                   /* send it as binary */                 03040000
  305. pipe = 'FBLOCK 8192'    /*  default processing  */                      03050000
  306.                                                                         03060000
  307.     End  /*  Select  type  */                                           03070000
  308.                                                                         03080000
  309.     'PIPE GOPSRVLS' root '| GOPSRVRP' path ,                            03090000
  310.             '|' pipe '| FBLOCK 8192 | STEM STEM.'                       03100000
  311.                                                                         03110000
  312. /*  If rc ^= 0 Then logrqest = logrqest "(rc=" || rc || ")"  */         03120000
  313.                                                                         03130000
  314. 'PIPE COMMAND XMITMSG' logmsg 'DAY MON DD TIME YY CLIENT PATH' ,        03140000
  315.         '(APPLID GOP CALLER SRV ERRMSG |' logpipe                       03150000
  316.                                                                         03160000
  317.                                                                         03170000
  318.     Say argo stem.0 "blocks to send"                                    03180000
  319.     /*                                                                  03190000
  320.      *   Send the response to our client                                03200000
  321.      */                                                                 03210000
  322.     Do i = 1 to stem.0                                                  03220000
  323.         bytes_out = Socket('Write', ns, stem.i)                         03230000
  324.         If bytes_out = "-1" Then Do                                     03240000
  325.             Say argo tcperror()                                         03250000
  326.             Leave                                                       03260000
  327.             End  /*  If  ..  Do  */                                     03270000
  328.         End  /*  Do  For  */                                            03280000
  329.                                                                         03290000
  330.                                                                         03300000
  331.     /*                                                                  03310000
  332.      *   All done, relinquish our socket descriptor                     03320000
  333.      */                                                                 03330000
  334.     rc = Socket('Close', ns)                                            03340000
  335.     If rc = "-1" Then Do                                                03350000
  336.         Say argo tcperror()                                             03360000
  337.         Leave                                                           03370000
  338.         End  /*  If  ..  Do  */                                         03380000
  339.     Say argo "Closed" ns "at" Time()                                    03390000
  340.                                                                         03400000
  341.                                                                         03410000
  342.     End  /*  Do  Forever  */                                            03420000
  343.                                                                         03430000
  344.                                                                         03440000
  345. /*                                                                      03450000
  346.  *   Tell RXSOCKET that we are done with this IUCV path                 03460000
  347.  */                                                                     03470000
  348. rc = Socket('Terminate')                                                03480000
  349. If rc = "-1" Then Do                                                    03490000
  350.     Say argo tcperror()                                                 03500000
  351.     End  /*  If  ..  Do  */                                             03510000
  352.                                                                         03520000
  353.                                                                         03530000
  354. Exit                                                                    03540000
  355.                                                                         03550000
  356.